package face.pay.util.bean;

import com.sun.org.apache.xpath.internal.operations.Or;
import face.pay.entity.OrderInfo;
import face.pay.util.bean.annotation.NotBind;
import org.apache.commons.lang3.time.DateUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.SecureRandom;
import java.util.*;

/**
 * 将一个bean转换成一个map
 */
public class JavaBeanUtils {

    private static final String SYMBOLS_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    private static final String SYMBOLS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private static final String SYMBOLSNUM = "0123456789";

    private static final Random RANDOM = new SecureRandom();

    public static Map<String,String> toMap(Object obj){
       Map<String,String> map = new HashMap<>();

       try{

           if(obj!=null){

               Class cls = obj.getClass();

               Field[] fields =  cls.getDeclaredFields();

               for(Field f :fields){
                   f.setAccessible(true);
                   String fileName =    f.getName();

                   NotBind notBind =  f.getAnnotation(NotBind.class);

                   if(notBind==null){
                       Class fileType =    f.getType();

                           Object value = f.get(obj);
                           if(value!=null){

                               map.put(fileName,value.toString());
                           }
                       }

                   }



           }else{
               return  map;
           }
       }catch (Exception e){
           e.printStackTrace();
       }
       return  map;
    }

    private static Map<String,String> supperToMap(Object obj){
        Map<String,String> map = new HashMap<>();

        try{

            if(obj!=null){

                Class cls = obj.getClass().getSuperclass();

                if(cls==null){
                    return  map;
                }
                Field[] fields =  cls.getDeclaredFields();

                for(Field f :fields){
                    f.setAccessible(true);
                    String fileName =    f.getName();

                    NotBind notBind =  f.getAnnotation(NotBind.class);

                    if(notBind==null){
                        Class fileType =    f.getType();

                        Object value = f.get(obj);
                        if(value!=null){

                            map.put(fileName,value.toString());
                        }
                    }

                }

            }else{
                return  map;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return  map;
    }

    /**
     * 将map对象转换成实体类
     * 映射成java对象 包含父级属性
     *
     * @param obj
     * @return
     */
    public static Map<String,String> allToMap(Object obj){
        Map<String,String> map = new HashMap<>();
        map = toMap(obj);
        map.putAll(supperToMap(obj));
        return  map;
    }



    public static Object mapToBean(Map<String,String> map,Class cls){

        try{

            if(map!=null){

                Constructor<?> cons = cls.getConstructor();
                Object obj =  cons.newInstance();

                Field[] fields =  cls.getDeclaredFields();

                for(Field f :fields){

                    String fileName =    f.getName();

                    String value = map.get(fileName);

                    if(value!=null){
                        Class typeClass =  f.getType();
                        f.setAccessible(true);
                        if(typeClass.equals(Long.class)){
                            f.set(obj,Long.parseLong(value));
                        }else  if(typeClass.equals(Integer.class)){
                            f.set(obj,Integer.parseInt(value));
                        }else  if(typeClass.equals(Double.class)){
                            f.set(obj,Double.parseDouble(value));
                        }else if(typeClass.equals(String.class)){
                            f.set(obj,value);
                        }
                    }
                }
                return  obj;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;
    }


    public static Object mapToBeanWithSupper(Map<String,String> map,Class cls){

        try{

            if(map!=null){

                Constructor<?> cons = cls.getConstructor();
                Object obj =  cons.newInstance();

                Field[] fields =  cls.getDeclaredFields();

                List<Field> list = new ArrayList<>(Arrays.asList(fields));

                Class supperClass = cls.getSuperclass();
                if(supperClass!=null){
                    Field[] supperFields =  supperClass.getDeclaredFields();

                    List<Field> supperList =  new ArrayList<>(Arrays.asList(supperFields));
                    list.addAll(supperList);
                }


                for(Field f :list){

                    String fileName =    f.getName();

                    String value = map.get(fileName);

                    if(value!=null){
                        Class typeClass =  f.getType();
                        f.setAccessible(true);
                        if(typeClass.equals(Long.class)){
                            f.set(obj,Long.parseLong(value));
                        }else  if(typeClass.equals(Integer.class)){
                            f.set(obj,Integer.parseInt(value));
                        }else  if(typeClass.equals(Double.class)){
                            f.set(obj,Double.parseDouble(value));
                        }else if(typeClass.equals(String.class)){
                            f.set(obj,value);
                        }
                    }
                }
                return  obj;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;
    }



    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generatesStringNonceStr(Integer length) {
        char[] nonceChars = new char[length];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }

    public static String generatesNumNonceStr(Integer length) {
        char[] nonceChars = new char[length];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLSNUM.charAt(RANDOM.nextInt(SYMBOLSNUM.length()));
        }
        return new String(nonceChars);
    }

    /**
     * 字母数字共六位混合随机字符串
     * @return
     */
    public static String getMixNonceString(){
        StringBuffer buffer = new StringBuffer();

        String str = generatesStringNonceStr(3);
        String num = generatesNumNonceStr(3);

        buffer.append(str);
        buffer.append(num);

        return buffer.toString();

    }

    public static String getMixString(Integer length){
        char[] nonceChars = new char[length];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS_STR.charAt(RANDOM.nextInt(SYMBOLS_STR.length()));
        }
        return new String(nonceChars);

    }




    public static void main(String[] args) {


        String  s = getMixString(12);

        System.out.println(s);

    }

}
